import core.globals
import core
import commands.shuffle

import ConfigParser
import argparse
import sys

class CommandLineExceptionHandler():

	def handle_expected_fatal_exception(self,msg_key,msg_params=()):
		message = globals.messages.get('exceptions',msg_key)
		message = message % msg_params
		prefix = 'Error: '
		print prefix + message

		sys.exit(1)
		
	def handle_unexpected_fatal_exception(self):
		type, value, ex_traceback = sys.exc_info()
		
		print "Exception of type '%s' occured: %s" % (type.__name__,value)
		print 'Stack trace:'
		print traceback.print_tb(ex_traceback)
		
		sys.exit(1)

def parse_command_line_args(remembered_login,remembered_pass):
	parser = argparse.ArgumentParser(description=globals.messages.get('help','description'))
	parser.add_argument('playlists', metavar='playlist', nargs='+', help=globals.messages.get('help','playlists'))
	parser.add_argument('-u', '--user',metavar='USERNAME',help=globals.messages.get('help','user'),default=remembered_login)
	parser.add_argument('-p', '--password',help=globals.messages.get('help','password'),default=remembered_pass)
	parser.add_argument('--remember-me', action='store_true',
						help=globals.messages.get('help','remember_me'))
	parser.add_argument('--remember-login', action='store_true',
						help=globals.messages.get('help','remember_login'))
	args = parser.parse_args()

	return args
	
def try_to_load_remembered_credentials():
	try:
		parser = ConfigParser.RawConfigParser()
		parser.read('credentials.cfg')
		#password only variant is not supported so we want code to throw exception here in that case
		login = parser.get('credentials','login')
		password = parser.get('credentials','password') if parser.has_option('credentials','password') else None
		return login, password
	except ConfigParser.Error:
		#it's ok if we from any reason can't read defaults - we just return None's
		return None, None
		
def remember_credentials(login,password=None):
	parser = ConfigParser.RawConfigParser()
	parser.add_section('credentials')
		
	parser.set('credentials','login',login)
	if password:
		parser.set('credentials','password',password)
	
	file = open('credentials.cfg','w')
	parser.write(file)
	file.close()
	
def print_info_to_console(key,params=()):
	message = globals.messages.get('info',key) % params
	print message

def perform():
	exception_handler = CommandLineExceptionHandler()
	globals.exception_handler = exception_handler
	
	remembered_login,remembered_pass = try_to_load_remembered_credentials()
	args = parse_command_line_args(remembered_login,remembered_pass)

	login,password = args.user, args.password
	if not login or not password:
		globals.exception_handler.handle_expected_fatal_exception('credentials_not_provided')

	try:
		authenticator = core.Authenticator(login,password)
		yt_service = authenticator.create_authenticated_yt_service()
		
		#it makes sense only after succesful authentication
		if args.remember_me:
			remember_credentials(login,password)
		elif args.remember_login:
			remember_credentials(login)
			
		print_info_to_console('started_shuffling')
		
		for playlist in args.playlists:
			print_info_to_console('shuffling_playlist',(playlist)) 
			
			playlist_mgr = core.PlaylistManager(yt_service,playlist)
			shuffler = commands.shuffle.Shuffler(playlist_mgr)
			shuffler.shuffle()
			
			print_info_to_console('done')
	except Exception, e:
		globals.exception_handler.handle_unexpected_fatal_exception()

	print_info_to_console('thanks')